// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraGameplayAbility_Death.h"

#include "AbilitySystem/Abilities/LyraGameplayAbility.h"
#include "AbilitySystem/LyraAbilitySystemComponent.h"
#include "Character/LyraHealthComponent.h"
#include "LyraGameplayTags.h"
#include "LyraLogChannels.h"
#include "Trace/Trace.inl"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraGameplayAbility_Death)

/**
 * 构造函数
 * @param ObjectInitializer 对象初始化器
 */
ULyraGameplayAbility_Death::ULyraGameplayAbility_Death(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor; // 每个Actor实例化
	NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::ServerInitiated; // 服务器初始化网络执行策略

	bAutoStartDeath = true; // 默认启用自动开始死亡

	if (HasAnyFlags(RF_ClassDefaultObject)) // 如果是类默认对象
	{
		// 将能力触发标签作为默认值添加到CDO。
		FAbilityTriggerData TriggerData;
		TriggerData.TriggerTag = LyraGameplayTags::GameplayEvent_Death; // 设置死亡事件触发标签
		TriggerData.TriggerSource = EGameplayAbilityTriggerSource::GameplayEvent; // 设置触发源为游戏事件
		AbilityTriggers.Add(TriggerData); // 添加触发数据
	}
}

/**
 * 激活死亡能力
 */
void ULyraGameplayAbility_Death::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
	check(ActorInfo); // 检查Actor信息有效性

	ULyraAbilitySystemComponent* LyraASC = CastChecked<ULyraAbilitySystemComponent>(ActorInfo->AbilitySystemComponent.Get()); // 获取Lyra能力系统组件

	FGameplayTagContainer AbilityTypesToIgnore; // 创建要忽略的能力类型容器
	AbilityTypesToIgnore.AddTag(LyraGameplayTags::Ability_Behavior_SurvivesDeath); // 添加"存活死亡"行为标签

	// 取消所有能力并阻止其他能力启动。
	LyraASC->CancelAbilities(nullptr, &AbilityTypesToIgnore, this); // 取消除指定类型外的所有能力

	SetCanBeCanceled(false); // 设置此能力不可被取消

	if (!ChangeActivationGroup(ELyraAbilityActivationGroup::Exclusive_Blocking)) // 尝试更改激活组为独占阻塞
	{
		UE_LOG(LogLyraAbilitySystem, Error, TEXT("ULyraGameplayAbility_Death::ActivateAbility: Ability [%s] failed to change activation group to blocking."), *GetName()); // 记录错误日志
	}

	if (bAutoStartDeath) // 如果启用了自动开始死亡
	{
		StartDeath(); // 开始死亡
	}

	Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData); // 调用父类激活能力
}

/**
 * 结束死亡能力
 */
void ULyraGameplayAbility_Death::EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled)
{
	check(ActorInfo); // 检查Actor信息有效性

	// 当能力结束时总是尝试完成死亡，以防能力没有完成。
	// 如果死亡尚未开始，这将不会执行任何操作。
	FinishDeath(); // 完成死亡

	Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled); // 调用父类结束能力
}

/**
 * 开始死亡序列
 */
void ULyraGameplayAbility_Death::StartDeath()
{
	if (ULyraHealthComponent* HealthComponent = ULyraHealthComponent::FindHealthComponent(GetAvatarActorFromActorInfo())) // 查找健康组件
	{
		if (HealthComponent->GetDeathState() == ELyraDeathState::NotDead) // 如果当前状态不是死亡
		{
			HealthComponent->StartDeath(); // 开始死亡
		}
	}
}

/**
 * 完成死亡序列
 */
void ULyraGameplayAbility_Death::FinishDeath()
{
	if (ULyraHealthComponent* HealthComponent = ULyraHealthComponent::FindHealthComponent(GetAvatarActorFromActorInfo())) // 查找健康组件
	{
		if (HealthComponent->GetDeathState() == ELyraDeathState::DeathStarted) // 如果死亡已开始
		{
			HealthComponent->FinishDeath(); // 完成死亡
		}
	}
}